/*
 * $Id: inet.h 140 2011-10-28 06:01:54Z hyunghwan.chung $
 *
   Copyright 2005-2009 Chung, Hyung-Hwan.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an  BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
 */

#ifndef _XP_NET_INET_H_
#define _XP_NET_INET_H_

#include <xp/types.h>
#include <xp/macros.h>
#include <xp/bas/endian.h>

/* 
 * MACRO: XP_INET4_CLASS_A
 *   Tests if an internet address belongs to class A (0-127)
 */
#define XP_INET4_CLASS_A(x) \
	((xp_ntoh32(x) & (xp_uint32_t)0x80000000) == (xp_uint32_t)0x00000000)

/* 
 * MACRO: XP_INET4_CLASS_B
 *   Tests if an internet address belongs to class B (128-191)
 */
#define XP_INET4_CLASS_B(x) \
	((xp_ntoh32(x) & (xp_uint32_t)0xC0000000) == (xp_uint32_t)0x80000000)

/* 
 * MACRO: XP_INET4_CLASS_C
 *   Tests if an internet address belongs to class C (192-223)
 */
#define XP_INET4_CLASS_C(x) \
	((xp_ntoh32(x) & (xp_uint32_t)0xE0000000) == (xp_uint32_t)0xC0000000)

#define XP_INET4_LOOPBACK 0x7f000001 /* 127.0.0.1 - host byte order*/
#define XP_INET4_IN_LOOPBACK(a) ((((long int)(a)) & 0xff000000) == 0x7f000000)

typedef xp_uint16_t xp_port_t;

typedef struct xp_ip4addr_t xp_ip4addr_t;
typedef struct xp_ip6addr_t xp_ip6addr_t;
typedef struct xp_ipaddr_t  xp_ipaddr_t;
typedef struct xp_ipaddrx_t xp_ipaddrx_t;

#include <xp/pack1.h>
struct xp_ip4addr_t
{
	xp_uint32_t value;
};

struct xp_ip6addr_t
{
	xp_byte_t value[16];
};
#include <xp/unpack.h>

enum xp_ipaddr_type_t
{
	XP_IPADDR_IP4,
	XP_IPADDR_IP6
};

typedef enum xp_ipaddr_type_t xp_ipaddr_type_t;

struct xp_ipaddr_t
{
	xp_ipaddr_type_t type;
	union  
	{
		xp_ip4addr_t ip4;
		xp_ip6addr_t ip6;
	} u;
};

struct xp_ipaddrx_t
{
	xp_ipaddr_type_t type;
	union  
	{
		xp_ip4addr_t ip4;
		xp_ip6addr_t ip6;
	} u;
	xp_uint16_t port;
};

#ifdef __cplusplus
extern "C" {
#endif

extern const xp_ip4addr_t xp_ip4addr_any;
extern const xp_ip4addr_t xp_ip4addr_loopback;
extern const xp_ip6addr_t xp_ip6addr_any;
extern const xp_ip6addr_t xp_ip6addr_loopback;

int xp_strtoip4addr (
	const xp_char_t* str,
	xp_ip4addr_t*    ipaddr
);

int xp_strxtoip4addr (
	const xp_char_t* str,
	xp_size_t        len,
	xp_ip4addr_t*    ipaddr
);

xp_size_t xp_ip4addrtostrx (
	const xp_ip4addr_t* ipaddr,
	xp_char_t*          buf,
	xp_size_t           size
);

int xp_strtoip6addr (
	const xp_char_t* str,
	xp_ip6addr_t*    ipaddr
);

int xp_strxtoip6addr (
	const xp_char_t* str,
	xp_size_t        len,
	xp_ip6addr_t*    ipaddr
);

xp_size_t xp_ip6addrtostrx (
	const xp_ip6addr_t* ipaddr,
	xp_char_t*          buf, 
	xp_size_t           size
);

int xp_strtoipaddr (
	const xp_char_t* str,
	xp_ipaddr_t*     ipaddr
);

int xp_strxtoipaddr (
	const xp_char_t* str,
	xp_size_t        len,
	xp_ipaddr_t*     ipaddr
);

int xp_strtoipaddrx (
	const xp_char_t* str,
	xp_ipaddrx_t*     ipaddrx
);

int xp_strxtoipaddrx (
	const xp_char_t* str,
	xp_size_t        len,
	xp_ipaddrx_t*    ipaddrx
);

int xp_ipaddrxequal (
	const xp_ipaddrx_t* a1,
	const xp_ipaddrx_t* a2
);

/*
 * FUNCTION: xp_inet4_strtoip
 *   Converts an internet address string to a binary address
 * 
 * PARAMETERS:
 *   str - [in] a null-terminated internet address in the standard notation
 *   ip - [out] a 32-bit IPv4 address
 *
 * RETURNS:
 *   0 on success, -1 on failure
 *
 * SEE ALSO:
 *   <xp_inet4_strxtoip> <xp_inet4_iptostrx>
 */
int xp_inet4_strtoip (const xp_char_t* str, xp_uint32_t* ip);

/*
 * FUNCTION: xp_inet4_strxtoip
 *   Converts a length-bounded internet address string to a binary address
 *
 * PARAMETERS:
 *   str - [in] a length-bounded internet address in the standard notation
 *   len - [in] the number of characters in the memory area pointed to by *str*
 *   ip - [out] a 32-bit IPv4 address
 *
 * RETURNS:
 *   0 on success, -1 on failure
 *
 * SEE ALSO:
 *   <xp_inet4_strtoip> <xp_inet4_iptostrx>
 */
int xp_inet4_strxtoip (const xp_char_t* str, xp_size_t len, xp_uint32_t* ip);

/*
 * FUNCTION: xp_inet4_iptostrx
 *   Converts an internet address to a string
 *
 * PARAMETERS:
 *   ip - [in] a 32-bit IPv4 address
 *   buf - [out] the buffer to hold a converted internet address string
 *   size - [in] the size of *buf*
 * 
 * RETURNS:
 *   The number characters in the buffer
 *
 * SEE ALSO:
 *   <xp_inet4_strtoip> <xp_inet4_strxtoip>
 */
xp_size_t xp_inet4_iptostrx (xp_uint32_t ip, xp_char_t* buf, xp_size_t size);

/*
 * FUNCTION: xp_inet4_pxtonm
 *   Converts a prefix length to a netmask
 */
int xp_inet4_pxtonm (int prefix, xp_uint32_t* netmask);

/*
 * FUNCTION: xp_inet4_nmtopx
 *   Converts a netmask to a prefix length
 */
int xp_inet4_nmtopx (xp_uint32_t netmask, int* prefix);

/*
 * FUNCTION: xp_inet4_strtoipnm
 *   Converts an ip/netmask string to numeric values
 *
 * PARAMETERS:
 *   str - [in] a string in an ip/netmask or an ip/prefix notation
 *   ip - [out] an ip address in the network byte order
 *   mask - [out] a netmask in the network byte order
 *
 * RETURNS:
 *   0 on success, -1 on failure
 * 
 * SEE ALSO:
 *   <xp_inet4_strxtoipnm>
 */
int xp_inet4_strtoipnm (
	const xp_char_t* str, xp_uint32_t* ip, xp_uint32_t* mask);

/*
 * FUNCTION: xp_inet4_strxtoipnm
 *   Converts an ip/netmask string to numeric values
 *
 * PARAMETERS:
 *   str - [in] a string in an ip/netmask or an ip/prefix notation
 *   len - [in] the length of *str*
 *   ip - [out] a pointer to memory area to hold an ip address 
 *   mask - [out] a poitner to memory area to hold a netmask
 *
 * RETURNS:
 *   0 on success, -1 on failure
 *
 * SEE ALSO:
 *   <xp_inet4_strtoipnm>
 */
int xp_inet4_strxtoipnm (
	const xp_char_t* str, xp_size_t len, xp_uint32_t* ip, xp_uint32_t* mask);

/*
 * FUNCTION: xp_inet4_ipnmtostrx
 *   Converts an internet address and a netmask to a string
 *
 * PARAMETERS:
 *   ip - [out] an ip address in the network byte order
 *   mask - [out] a netmask in the network byte order
 *   buf - [out] pointer to a buffer to hold result
 *   size - [in] buffer size
 *
 * DESCRIPTION:
 *   When the ip address and the netmask are converted to a string, 
 *   the internet address part of the string is followed by a slash and
 *   the netmask in the format of xxx.xxx.xxx.xxx.
 *
 * RETURNS:
 *   Length of the resulting string
 *
 * SEE ALSO:
 *   <xp_inet4_ipnmtostrpx>
 */
xp_size_t xp_inet4_ipnmtostrx (
	xp_uint32_t ip, xp_uint32_t mask, xp_char_t* buf, xp_size_t size);

/*
 * FUNCTION: xp_inet4_ipnmtostrpx
 *   Converts an internet address and a netmask to a string
 *
 * PARAMETERS:
 *   ip - [out] an ip address in the network byte order
 *   mask - [out] a netmask in the network byte order
 *   buf - [out] pointer to a buffer to hold result
 *   size - [in] buffer size
 *
 * RETURNS:
 *   Length of the resulting string on success, (xp_size_t)-1 on failure.
 *
 * DESCRIPTION:
 *   The netmask is converted to a prefix-length and appened to the resulting
 *   string following an ip address part and a slash. If it cannot be converted
 *   to a prefix-length, (xp_size_t)-1 is returned.
 *
 * SEE ALSO:
 *   <xp_inet4_ipnmtostrx>
 */
xp_size_t xp_inet4_ipnmtostrpx (
	xp_uint32_t ip, xp_uint32_t mask, xp_char_t* buf, xp_size_t size);



/*
int xp_inet_resolve (
	const xp_char_t* host, const xp_char_t* service,
	xp_port_t* port, xp_ipaddr_t* ip);
*/

#ifdef __cplusplus
}
#endif

#endif
